<?php

class Model_Events
{

    private $event=null;
    private $sport=null;
    private $idEvent=null;


    public function __construct() {
        $this->prepareConnection();
    }

    public function getSport(){
        if($this->sport==null){
            $sports = Zend_Registry::get('sports');
            $this->sport = $sports[$this->event['s']];
        }
        return $this->sport;
    }

    private function prepareConnection(){
        if (!isset($this->db)){
            $db = Zend_Registry::get("db_main");
            if (!$db->connected) $db->connect();
            $this->db = $db->escoreboar;
        }
    }

    public function find($query, $sort, $limit=-1){
        $events = $this->db->event->find($query)->sort($sort);
        if ($limit!=-1)
            return $events->limit($limit);
        else
            return $events;
    }
    
    public function get($idEvent){
        if($this->idEvent==null || $this->idEvent!=$idEvent){
            $this->idEvent=$idEvent;
            $this->event=null;
        }
        if($this->event==null)
            $this->event = $this->db->event->findOne( array('_id' =>new MongoId($idEvent)) );
        return $this->event;

    }
    public function getPossibleActions($idEvent){
        $event=$this->get($idEvent);
        $sports=new Model_Sports();
        //TODO: overrides

        $sport=$sports->get($event['s']);
        return $sport['as'];
    }

    private function addKeywords(&$keywords, $phrase)
    {
        foreach (explode(" ", $phrase) as $word)
            $keywords[$word] = 1;
    }

    public function create($idUser, $idSport, $startTime, $description, $location, $participants, $tags){
        $this->prepareConnection();
        $teams=null;
        $keywords = array();
        foreach($participants as $p){
            $this->addKeywords($keywords, $p);
            $teams[]=array("n"=>$p,"s"=>0);
        }

        $this->addKeywords($keywords, $description);
        $this->addKeywords($keywords, $location);
        foreach($tags as $t) $this->addKeywords($keywords, $t);

        $data=array("u"=>$idUser, "s"=>$idSport,"st"=>$startTime, "lu"=>new MongoDate(), "c"=>$description,
            "l"=>$location,"ps"=>$teams, "ts"=>$tags, "_keywords" => array_keys($keywords) );

        if($this->db->event->insert($data, true))
            return $data["_id"];
        else
            return false;
    }
    
    public function exists($idSport, $startTime, $description, $location){
        $this->prepareConnection();
        $data=array("s"=>$idSport,"st"=>$startTime, "c"=>$description, "l"=>$location);
        return $this->db->event->findOne($data)!=null;

    }
    public function getAction($idEvent, $idx){
        $event=$this->get($idEvent);
        return $event['as'][$idx];
    }
    public function putAction($idEvent, $second, $idAction, $team, $sequence=""){
        
        $event=$this->get($idEvent);
        $actions=isset($event['as'])?$event['as']:array();
        if($sequence=="")
            $sequence=count($actions);


        if (isset($actions[$sequence])){
            die("duplicate action.");
            return false;
        }

        //obtiene el value de la accion
        $sports=new Model_Sports();
        $sport=$sports->get($event['s']);
        $value=0;
        if ($idAction>-1)
            $value=$sport['as'][$idAction]['v'];

        $psData=array();
        if($value>0){
            $ps=$event['ps'];
            $ps[$team]['s']+=$value;
            $psData=array("ps"=>$ps);
        }


        $actions[$sequence]=array("s"=>$sequence, "t"=>$second, "a"=>$idAction, "p"=>$team);
        $this->prepareConnection();
        $set = array('$set' => array_merge(array("as" => $actions,"lu"=>new MongoDate()),$psData));
        return $this->db->event->update(array('_id' =>new MongoId($idEvent)),$set);
        

    }
    public function removeAction($idEvent, $sequence){
        $event=$this->get($idEvent);
        $actions=$event['as'];
        if (!isset($actions[$sequence]))
            return false;

        $actions[$sequence]['d']=1;
        $this->prepareConnection();
        $set = array('$set' => array("as" => $actions));
        return $this->db->event->update(array('_id' =>new MongoId($idEvent)),$set);
    }

    public function recentEvents($count){
        $this->prepareConnection();
        $recent  =array();
        $cursor = $this->db->event->find(array(), array("s"=>1, "ps"=>1, "c"=>1, "tm"=>1, "as"=>array('$slice'=>-1)))->sort(array("lu"=>-1))->limit($count);
        foreach ($cursor as $event) {
            $recent []= $event;
        }
        unset ($cursor);
        return $recent;
    }

    public function updateTime($idEvent, $part, $time){
        $event = $this->db->event->findOne( array('_id' =>new MongoId($idEvent)) );

        $tm=isset($event['tm'])?$event['tm']:array();
        $tm[$part]=$time;
        //real start time

        $rst=isset($event['rst'])?$event['rst']:new MongoDate();

        $set = array('$set' => array("tm" => $tm, "rst"=>$rst));
        return $this->db->event->update(array('_id' =>new MongoId($idEvent)),$set);
        
    }

    //Comprueba la consistencia de los tiempos
    public function checkStatus(){
        
        $event=$this->get($this->idEvent);
        //Si tiene una actualización en los últimos 5 minutos se da por bueno.

        if(time()-$event['lu']->sec<300)
                return true;

        $sport=$this->getSport();
        $tm = isset($event["tm"])?$event["tm"]:array();
        if(count($sport['parts']) < count($tm))
            return true;

        $part = 0;
        $time = 0;
        if (count($time)>0){
            $part = count($tm);
            $time = $tm[$part-1];
        }
        
        //Si la parte tiene más de un 20% del tiempo previsto se termina la parte
        
        if($time>(($sport["parts"]["part_".($part-1)]['duration']*60)*1.2)){
            //TODO: si es la última parte hay que dar por terminado el evento
            $this->updateTime ($this->idEvent, $part, 0);
        }
        
    }
}

